#pragma once

#include "EventLoop.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "nocopy.h"
#include "TcpConnection.h"
#include "Buffer.h"
#include <functional>
#include <string>
#include "EventLoopThreadPool.h"
#include "Callbacks.h"
#include <atomic>
#include<unordered_map>

// #pragma once

// /**
//  * 用户使用muduo编写服务器程序
//  */ 
// #include "EventLoop.h"
// #include "Acceptor.h"
// #include "InetAddress.h"
// #include "nocopy.h"
// #include "EventLoopThreadPool.h"
// #include "Callbacks.h"
// #include "TcpConnection.h"
// #include "Buffer.h"

// #include <functional>
// #include <string>
// #include <memory>
// #include <atomic>
// #include <unordered_map>

class TcpServer : nocopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop *)>;

    enum Option{
        KNoReusePort,
        KReusePort
    };

    TcpServer(EventLoop*loop,const InetAddress& listenAddr,const std::string& name,Option option=KNoReusePort);
    ~TcpServer();

    void setThreadInitCallback(const ThreadInitCallback& cb){threadInitCallback_=cb;}
    void setConnectionCAllback(const ConnectionCallback& cb){ConnectionCallback_=cb;}
    void setMessageCallback(const MessageCallback& cb){MessageCallback_=cb;}
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) {WriteCompleteCallback_=cb;}

    void setThreadNum(int numThreads);//设置subLoop数量

    void start();//开启服务监听

private:

    void newConnection(int sockfd,const InetAddress& peerAddr) ;
    void removeConnection(const TcpConnectionPtr& conn); 
    void removeConnectionInLoop(const TcpConnectionPtr& conn);
    using ConnectionMap=std::unordered_map<std::string,TcpConnectionPtr>;

    EventLoop *loop_;
    const std::string IpPort_;
    const std::string name_;
    std::unique_ptr<Acceptor> acceptor_;//运行在mainLoop,任务是监听连接事件
    std::shared_ptr<EventLoopThreadPool> threadPool_; // 一个线程一个loop

    ConnectionCallback ConnectionCallback_;//有新链接时的回调
    MessageCallback MessageCallback_;//有读写消息时的回调
    WriteCompleteCallback WriteCompleteCallback_;//消息发送完成后的回调

    ThreadInitCallback threadInitCallback_;//线程初始化的回调
    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_;
};
